home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / dev / c / ctags.lha / ctags-3.0.3 / eiffel.c < prev    next >
C/C++ Source or Header  |  1999-02-17  |  25KB  |  1,018 lines

  1. /*****************************************************************************
  2. *   $Id: eiffel.c,v 7.5 1998/12/21 05:55:09 darren Exp $
  3. *
  4. *   Copyright (c) 1998, Darren Hiebert
  5. *
  6. *   This source code is released for free distribution under the terms of the
  7. *   GNU General Public License.
  8. *
  9. *   This module contains functions for generating tags for Eiffel language
  10. *   files.
  11. *****************************************************************************/
  12.  
  13. /*============================================================================
  14. =   Include files
  15. ============================================================================*/
  16. #include "general.h"
  17.  
  18. #include <string.h>
  19. #include <limits.h>
  20. #include <ctype.h>    /* to define tolower() */
  21. #include <setjmp.h>
  22.  
  23. #include "debug.h"
  24. #include "parse.h"
  25. #include "entry.h"
  26. #include "keyword.h"
  27. #include "main.h"
  28. #include "options.h"
  29. #include "read.h"
  30. #include "vstring.h"
  31.  
  32. /*============================================================================
  33. =   Macros
  34. ============================================================================*/
  35. #define isFreeOperatorChar(c)    ((c) == '@' || (c) == '#' || \
  36.                  (c) == '|' || (c) == '&')
  37. #define isType(token,t)        (boolean)((token)->type == (t))
  38. #define isKeyword(token,k)    (boolean)((token)->keyword == (k))
  39.  
  40. /*============================================================================
  41. =   Data declarations
  42. ============================================================================*/
  43.  
  44. typedef enum eException { ExceptionNone, ExceptionEOF } exception_t;
  45.  
  46. /*  Used to specify type of keyword.
  47.  */
  48. typedef enum eKeywordId {
  49.     KEYWORD_NONE,
  50.     KEYWORD_alias, KEYWORD_all, KEYWORD_and, KEYWORD_as, KEYWORD_check,
  51.     KEYWORD_class, KEYWORD_creation, KEYWORD_Current, KEYWORD_debug,
  52.     KEYWORD_deferred, KEYWORD_do, KEYWORD_else, KEYWORD_elseif, KEYWORD_end,
  53.     KEYWORD_ensure, KEYWORD_expanded, KEYWORD_export, KEYWORD_external,
  54.     KEYWORD_false, KEYWORD_feature, KEYWORD_from, KEYWORD_frozen, KEYWORD_if,
  55.     KEYWORD_implies, KEYWORD_indexing, KEYWORD_infix, KEYWORD_inherit,
  56.     KEYWORD_inspect, KEYWORD_invariant, KEYWORD_is, KEYWORD_like,
  57.     KEYWORD_local, KEYWORD_loop, KEYWORD_not, KEYWORD_obsolete, KEYWORD_old,
  58.     KEYWORD_once, KEYWORD_or, KEYWORD_prefix, KEYWORD_redefine, KEYWORD_rename,
  59.     KEYWORD_require, KEYWORD_rescue, KEYWORD_Result, KEYWORD_retry,
  60.     KEYWORD_select, KEYWORD_separate, KEYWORD_strip, KEYWORD_then,
  61.     KEYWORD_true, KEYWORD_undefine, KEYWORD_unique, KEYWORD_until,
  62.     KEYWORD_variant, KEYWORD_when, KEYWORD_xor
  63. } keywordId;
  64.  
  65. /*  Used to determine whether keyword is valid for the token language and
  66.  *  what its ID is.
  67.  */
  68. typedef struct sKeywordDesc {
  69.     const char *name;
  70.     keywordId id;
  71. } keywordDesc;
  72.  
  73. typedef enum eTokenType {
  74.     TOKEN_UNDEFINED,
  75.     TOKEN_BANG,
  76.     TOKEN_CHARACTER,
  77.     TOKEN_CLOSE_BRACE,
  78.     TOKEN_CLOSE_BRACKET,
  79.     TOKEN_CLOSE_PAREN,
  80.     TOKEN_COMMA,
  81.     TOKEN_COLON,
  82.     TOKEN_DOT,
  83.     TOKEN_DOLLAR,
  84.     TOKEN_IDENTIFIER,
  85.     TOKEN_KEYWORD,
  86.     TOKEN_NUMERIC,
  87.     TOKEN_OPEN_BRACE,
  88.     TOKEN_OPEN_BRACKET,
  89.     TOKEN_OPEN_PAREN,
  90.     TOKEN_OPERATOR,
  91.     TOKEN_OTHER,
  92.     TOKEN_SEPARATOR,
  93.     TOKEN_STRING
  94. } tokenType;
  95.  
  96. typedef enum eTagType {
  97.     TAG_UNDEFINED,
  98.     TAG_CLASS,
  99.     TAG_FEATURE,
  100.     TAG_LOCAL,
  101.     TAG_COUNT        /* must be last */
  102. } tagType;
  103.  
  104. typedef struct sTokenInfo {
  105.     tokenType    type;
  106.     keywordId    keyword;
  107.     boolean    isExported;
  108.     vString *    string;
  109.     vString *    className;
  110.     vString *    featureName;
  111. } tokenInfo;
  112.  
  113. /*============================================================================
  114. =   Data definitions
  115. ============================================================================*/
  116.  
  117. static jmp_buf Exception;
  118.  
  119. static const keywordDesc EiffelKeywordTable[] = {
  120.     /* keyword        keyword ID */
  121.     { "alias",        KEYWORD_alias        },
  122.     { "all",        KEYWORD_all        },
  123.     { "and",        KEYWORD_and        },
  124.     { "as",        KEYWORD_as        },
  125.     { "check",        KEYWORD_check        },
  126.     { "class",        KEYWORD_class        },
  127.     { "creation",    KEYWORD_creation    },
  128.     { "current",    KEYWORD_Current        },
  129.     { "debug",        KEYWORD_debug        },
  130.     { "deferred",    KEYWORD_deferred    },
  131.     { "do",        KEYWORD_do        },
  132.     { "else",        KEYWORD_else        },
  133.     { "elseif",        KEYWORD_elseif        },
  134.     { "end",        KEYWORD_end        },
  135.     { "ensure",        KEYWORD_ensure        },
  136.     { "expanded",    KEYWORD_expanded    },
  137.     { "export",        KEYWORD_export        },
  138.     { "external",    KEYWORD_external    },
  139.     { "false",        KEYWORD_false        },
  140.     { "feature",    KEYWORD_feature        },
  141.     { "from",        KEYWORD_from        },
  142.     { "frozen",        KEYWORD_frozen        },
  143.     { "if",        KEYWORD_if        },
  144.     { "implies",    KEYWORD_implies        },
  145.     { "indexing",    KEYWORD_indexing    },
  146.     { "infix",        KEYWORD_infix        },
  147.     { "inherit",    KEYWORD_inherit        },
  148.     { "inspect",    KEYWORD_inspect        },
  149.     { "invariant",    KEYWORD_invariant    },
  150.     { "is",        KEYWORD_is        },
  151.     { "like",        KEYWORD_like        },
  152.     { "local",        KEYWORD_local        },
  153.     { "loop",        KEYWORD_loop        },
  154.     { "not",        KEYWORD_not        },
  155.     { "obsolete",    KEYWORD_obsolete    },
  156.     { "old",        KEYWORD_old        },
  157.     { "once",        KEYWORD_once        },
  158.     { "or",        KEYWORD_or        },
  159.     { "prefix",        KEYWORD_prefix        },
  160.     { "redefine",    KEYWORD_redefine    },
  161.     { "rename",        KEYWORD_rename        },
  162.     { "require",    KEYWORD_require        },
  163.     { "rescue",        KEYWORD_rescue        },
  164.     { "result",        KEYWORD_Result        },
  165.     { "retry",        KEYWORD_retry        },
  166.     { "select",        KEYWORD_select        },
  167.     { "separate",    KEYWORD_separate    },
  168.     { "strip",        KEYWORD_strip        },
  169.     { "then",        KEYWORD_then        },
  170.     { "true",        KEYWORD_true        },
  171.     { "undefine",    KEYWORD_undefine    },
  172.     { "unique",        KEYWORD_unique        },
  173.     { "until",        KEYWORD_until        },
  174.     { "variant",    KEYWORD_variant        },
  175.     { "when",        KEYWORD_when        },
  176.     { "xor",        KEYWORD_xor        }
  177. };
  178.  
  179. /*============================================================================
  180. =   Function prototypes
  181. ============================================================================*/
  182. static void buildEiffelKeywordHash __ARGS((void));
  183. static const char *tagName __ARGS((const tagType type));
  184. static int tagLetter __ARGS((const tagType type));
  185. static boolean includeTag __ARGS((const tagType type, const boolean fileScope));
  186. static void qualifyClassTag __ARGS((tokenInfo *const token));
  187. static void qualifyFeatureTag __ARGS((tokenInfo *const token));
  188. static void qualifyLocalTag __ARGS((tokenInfo *const token));
  189. static int skipToCharacter __ARGS((const int c));
  190. static vString *parseInteger __ARGS((int c));
  191. static vString *parseNumeric __ARGS((int c));
  192. static int parseEscapedCharacter __ARGS((void));
  193. static int parseCharacter __ARGS((void));
  194. static void parseString __ARGS((vString *const string));
  195. static void parseIdentifier __ARGS((vString *const string, const int firstChar));
  196. static void parseFreeOperator __ARGS((vString *const string, const int firstChar));
  197. static keywordId analyzeToken __ARGS((vString *const name));
  198. static void readToken __ARGS((tokenInfo *const token));
  199. static boolean isIdentifierMatch __ARGS((const tokenInfo *const token, const char *const name));
  200. static void locateToken __ARGS((tokenInfo *const token, const tokenType type));
  201. static void skipPastMatchingBracket __ARGS((tokenInfo *const token));
  202. static void skipEntityType __ARGS((tokenInfo *const token));
  203. static void parseLocal __ARGS((tokenInfo *const token));
  204. static void findFeatureEnd __ARGS((tokenInfo *const token));
  205. static boolean readFeatureName __ARGS((tokenInfo *const token));
  206. static void parseFeature __ARGS((tokenInfo *const token));
  207. static void parseExport __ARGS((tokenInfo *const token));
  208. static void locateKeyword __ARGS((tokenInfo *const token, const keywordId keyword));
  209. static void parseFeatureClauses __ARGS((tokenInfo *const token));
  210. static void parseRename __ARGS((tokenInfo *const token));
  211. static void parseInherit __ARGS((tokenInfo *const token));
  212. static void parseClass __ARGS((tokenInfo *const token));
  213. static tokenInfo *newToken __ARGS((void));
  214. static void deleteToken __ARGS((tokenInfo *const token));
  215. static void init __ARGS((void));
  216.  
  217. /*============================================================================
  218. =   Function definitions
  219. ============================================================================*/
  220.  
  221. static void buildEiffelKeywordHash()
  222. {
  223.     const